﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Confucius.dao;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Windows.Resources;
using Confucius.entity;
using Confucius.utils;
using DBContent.Model;

namespace Confucius.daoImpl
{
    /// <summary>
    /// Author:Liangchuan Gu
    /// date:2012-04-01
    /// </summary>
    public class GameDAOImpl : GameDAO
    {
        App mainApp;

        public GameDAOImpl(App currentApp)
        {
            this.mainApp = currentApp;
        }

        public List<GameHeader> findLocalGames()
        {
            return null;
        }

        public String getLocalGameName(String gameID)
        {
            List<GameHeader> remoteGames = new List<GameHeader>();
            try
            {
                Uri uri = new Uri("assets/gameList.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);
                remoteGames = getRemoteGameListByXML(loadedData);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("Parsing gameList.xml failed: " + e.Message);
            }

            for (int i = 0; i < remoteGames.Count; i++)
            {
                if (remoteGames.ElementAt(i).GameID.Equals(gameID)) 
                {
                    return remoteGames.ElementAt(i).GameName;
                }

            }

            return null;

        }

        public List<GameHeader> findRemoteGames()
        {
            List<GameHeader> remoteGames = new List<GameHeader>();

            try
            {
                Uri uri = new Uri("assets/gameList.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);
                remoteGames = getRemoteGameListByXML(loadedData);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("Parsing gameList.xml failed: " + e.Message);
            }

            for (int i = 0; i < remoteGames.Count; i++)
            {
                System.Console.WriteLine("GameID: {0}", remoteGames.ElementAt(i).GameID);
                System.Console.WriteLine("GameName: {0}", remoteGames.ElementAt(i).GameName);
                System.Console.WriteLine("IconID: {0}", remoteGames.ElementAt(i).IconID);
                System.Console.WriteLine("Status: {0}", remoteGames.ElementAt(i).Status);
                System.Console.WriteLine("Version: {0}", remoteGames.ElementAt(i).Version);
            }
            // Update in DB
            foreach (GameHeader game in remoteGames)
            {
                DBGame dbGame = new DBGame();
                dbGame.GameID = game.GameID;
                Boolean isGameInDB = ConfuciusDBHelper.IsRecordIn<DBGame>(dbGame);
                if (isGameInDB)
                {
                    string oldVersion = ConfuciusDBHelper.getGameVersion(dbGame);
                    string oldStatus = ConfuciusDBHelper.getGameStatus(dbGame);
                    if (oldVersion == game.Version)
                    {
                        game.Status = oldStatus;
                    }
                    else
                    {
                        game.Status = Game.READY_STATUS;
                        dbGame.Version = game.Version;
                        string tempStatus = dbGame.Status;
                        dbGame.Status = Game.START_STATUS;
                        ConfuciusDBHelper.updateGame(dbGame);
                        dbGame.Status = tempStatus;
                    }
                }
                else
                {
                    dbGame.Status = Game.READY_STATUS;
                    dbGame.Version = game.Version;
                    ConfuciusDBHelper.Add<DBGame>(dbGame);
                    game.Status = Game.READY_STATUS;
                }
            }
            return remoteGames;
        }

        public List<GameHeader> getRemoteGameListByXML(XDocument xmlDoc)
        {
            var games = from gameElement in xmlDoc.Descendants("game")
                        select gameElement;
            List<GameHeader> gameHeaderList = new List<GameHeader>();
            foreach (XElement gameElement in games)
            {
                GameHeader header = new GameHeader()
                {
                    GameID = (string)gameElement.Element("gameID").Value,
                    IconID = (string)gameElement.Element("iconID").Value,
                    Description = (string)gameElement.Element("description").Value,
                    GameName = (string)gameElement.Element("gameName").Value,
                    Version = (string)gameElement.Element("version").Value
                };
                gameHeaderList.Add(header);
            }
            return gameHeaderList;
        }

        public Game readGameDetail(string gameID)
        {
            try
            {
                Uri uri = new Uri("assets/gameFiles/" + gameID + "/game.xml", UriKind.Relative);
                StreamResourceInfo resourceInfo = Application.GetResourceStream(uri);
                XDocument loadedData = XDocument.Load(resourceInfo.Stream);
                return getGameInfoByXML(loadedData, gameID);
            }
            catch (Exception e)
            {
                throw new Exception("Could not read Game from XML. ID is: " + gameID + ". Info is: " + e.Message);
            }

        }

        private Game getGameInfoByXML(XDocument xmlDoc, string gameID)
        {
            var games = from gameElement in xmlDoc.Descendants("game")
                        select gameElement;

            foreach (XElement element in games)
            {

                Game matchedGame = new Game();
                matchedGame.PublishTitle = (string)element.Element("publishtitle").Value;
                matchedGame.PublishDescription = (string)element.Element("publishdescription").Value;
                matchedGame.IconID = (string)element.Element("iconID").Value;
                matchedGame.GameCoverID = (string)element.Element("gameCoverID").Value;
                matchedGame.Introduction = (string)element.Element("introduction").Value;
                matchedGame.Ending = (string)element.Element("ending").Value;
                matchedGame.Author = (string)element.Element("author").Value;
                matchedGame.Email = (string)element.Element("email").Value;
                matchedGame.PublishAgent = (string)element.Element("publishagent").Value;

                return matchedGame;

            }

            return null;
        }

        public void updateGameStatus(string gameID, string status)
        {
            DBGame dbGame = new DBGame();
            dbGame.GameID = gameID;
            dbGame.Status = status;
            ConfuciusDBHelper.updateGame(dbGame);

        }
        /*
         * Initialize game content with specific gameID
         */
        public void populdateGame(string gameID)
        {
            NPCDAO npcDAO = new NPCDAOImpl();
            QuestDAO questDAO = new QuestDAOImpl();
            ItemDAO itemDAO = new ItemDAOImpl();
            GameRuleDAO gameRuleDAO = new GameRuleDAOImpl();
            List<NPC> npcs = npcDAO.retrieveNPCs(gameID);
            List<Quest> quests = questDAO.retreiveQuests(gameID);
            List<Item> items = itemDAO.retreiveItems(gameID);
            List<String> triggerIDs = gameRuleDAO.retrieveTriggerIDs(gameID);

            foreach (NPC npc in npcs)
            {
                DBNpc dbNpc = new DBNpc();
                dbNpc.NpcID = npc.NpcID;
                dbNpc.GameID = gameID;
                dbNpc.Status = npc.Chattable;
                ConfuciusDBHelper.Add<DBNpc>(dbNpc);
            }

            foreach (Quest quest in quests)
            {
                DBQuest dbQuest = new DBQuest();
                dbQuest.QuestID = quest.QuestID;
                dbQuest.GameID = gameID;
                dbQuest.Status = Quest.NOT_CHECKED_IN_STATUS;
                dbQuest.Duration = "--:--:--";
                ConfuciusDBHelper.Add<DBQuest>(dbQuest);
            }

            foreach (Item item in items)
            {
                DBItem dbItem = new DBItem();
                dbItem.ItemID = item.ItemID;
                dbItem.GameID = gameID;
                dbItem.Status = item.Pickable;
                ConfuciusDBHelper.Add<DBItem>(dbItem);
            }

            foreach (String triggerID in triggerIDs)
            {
                DBTrigger dbTrigger = new DBTrigger();
                dbTrigger.TriggerID = triggerID;
                dbTrigger.GameID = gameID;
                dbTrigger.Status = Trigger.NOT_TRIGGER_STATUS;
                ConfuciusDBHelper.Add<DBTrigger>(dbTrigger);
            }
        }

    }
}
